package cn.stylefeng.guns.modular.cb.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.*;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import cn.stylefeng.guns.modular.cb.service.WxMsgService;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;

@Service
public class WxMsgServiceImpl implements WxMsgService {

    @Value("${wx.appid}")
    private String appId;

    @Value("${wx.secret}")
    private String secret;

    @Value("${wx.config.token}")
    private String token;

    @Value("${wx.config.aesKey}")
    private String aesKey;

    @Value("${wx.config.msgDataFormat}")
    private String msgDataFormat;

    private static Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
    private static Map<String, WxMaService> maServices = Maps.newHashMap();

    @PostConstruct
    public void init() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(secret);
        config.setToken(token);
        config.setAesKey(aesKey);
        config.setMsgDataFormat(msgDataFormat);

        WxMaService service = new WxMaServiceImpl();
        service.setWxMaConfig(config);
        routers.put(appId, this.newRouter(service));
        maServices.put(appId, service);
    }

    /**
     * 微信小程序推送订阅消息
     * create By KingYiFan on 2020/01/06
     */
    @Override
    public Object sendDYTemplateMessage(String openId, String page, String templateId, JSONObject jsonObject) {

        WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage();

        //跳转小程序页面路径
        subscribeMessage.setPage(page);
        //模板消息id
        subscribeMessage.setTemplateId(templateId);
        //给谁推送 用户的openid （可以调用根据code换openid接口)
        subscribeMessage.setToUser(openId);
        //==========================================创建一个参数集合========================================================
        ArrayList<WxMaSubscribeData> wxMaSubscribeData = new ArrayList<>();

//        订阅消息参数值内容限制说明
//              ---摘自微信小程序官方：https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
//        参数类别 	参数说明 	参数值限制 	   说明
//        thing.DATA 	事物 	20个以内字符 	可汉字、数字、字母或符号组合
//        number.DATA 	数字 	32位以内数字 	只能数字，可带小数
//        letter.DATA 	字母 	32位以内字母 	只能字母
//        symbol.DATA 	符号 	5位以内符号 	只能符号
//        character_string.DATA 	字符串 	32位以内数字、字母或符号 	可数字、字母或符号组合
//        time.DATA 	时间 	24小时制时间格式（支持+年月日） 	例如：15:01，或：2019年10月1日 15:01
//        date.DATA 	日期 	年月日格式（支持+24小时制时间） 	例如：2019年10月1日，或：2019年10月1日 15:01
//        amount.DATA 	金额 	1个币种符号+10位以内纯数字，可带小数，结尾可带“元” 	可带小数
//        phone_number.DATA 	电话 	17位以内，数字、符号 	电话号码，例：+86-0766-66888866
//        car_number.DATA 	车牌 	8位以内，第一位与最后一位可为汉字，其余为字母或数字 	车牌号码：粤A8Z888挂
//        name.DATA 	姓名 	10个以内纯汉字或20个以内纯字母或符号 	中文名10个汉字内；纯英文名20个字母内；中文和字母混合按中文名算，10个字内
//        phrase.DATA 	汉字 	5个以内汉字 	5个以内纯汉字，例如：配送中

        for (Map.Entry entry : jsonObject.entrySet()) {
            String name = entry.getKey().toString();
            String value = entry.getValue().toString();

            WxMaSubscribeData wxMaSubscribeData1 = new WxMaSubscribeData();
            wxMaSubscribeData1.setName(name);
            wxMaSubscribeData1.setValue(value);
            //每个参数 存放到大集合中
            wxMaSubscribeData.add(wxMaSubscribeData1);
        }

        //第一个内容： 奖品名称
//        WxMaSubscribeData wxMaSubscribeData1 = new WxMaSubscribeData();
//        wxMaSubscribeData1.setName("thing1");
//        wxMaSubscribeData1.setValue("充气娃娃豪华版");
//        //每个参数 存放到大集合中
//        wxMaSubscribeData.add(wxMaSubscribeData1);


        //把集合给大的data
        subscribeMessage.setData(wxMaSubscribeData);
        //=========================================封装参数集合完毕========================================================

        try {
            WxMaService wxService = maServices.get(appId);
            //进行推送
            wxService.getMsgService().sendSubscribeMsg(subscribeMessage);
            return "推送成功";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "推送失败";
    }

    private WxMaService getWxMaService(){
        //获取微信小程序配置：
        WxMaService wxService = new WxMaServiceImpl();
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(secret);
        config.setToken(token);
        config.setAesKey(aesKey);
        config.setMsgDataFormat(msgDataFormat);
        wxService.setWxMaConfig(config);
        return wxService;
    }

    private WxMaMessageRouter newRouter(WxMaService service) {
        final WxMaMessageRouter router = new WxMaMessageRouter(service);
        router
                .rule().handler(logHandler).next()
                .rule().async(false).content("模板").handler(templateMsgHandler).end()
                .rule().async(false).content("文本").handler(textHandler).end()
                .rule().async(false).content("图片").handler(picHandler).end()
                .rule().async(false).content("二维码").handler(qrcodeHandler).end();
        return router;
    }

    private final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
                .templateId("IJNQwvUi_E1FdvTRdXgY6WdJx6YtFuFAhO7yrTaO_5Y")
                .formId("自己替换可用的formid")
                .data(Lists.newArrayList(
                        new WxMaTemplateData("keyword1", "339208499", "#173177")))
                .toUser(wxMessage.getFromUser())
                .build());
        return null;
    };

    private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
        System.out.println("收到消息：" + wxMessage.toString());
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为：" + wxMessage.toJson())
                .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
                .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            WxMediaUploadResult uploadResult = service.getMediaService()
                    .uploadMedia("image", "png",
                            ClassLoader.getSystemResourceAsStream("tmp.png"));
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(wxMessage.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

    private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            final File file = service.getQrcodeService().createQrcode("123", 430);
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(wxMessage.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };
}
